package com.GraduationDesign.backend.blImpl.codeQuality;

import com.GraduationDesign.backend.bl.codeQuality.CodeQualityService;
import com.GraduationDesign.backend.data.codeQuality.QualityMapper;
import com.GraduationDesign.backend.data.codeQuality.QualitydataMapper;
import com.GraduationDesign.backend.po.Quality;
import com.GraduationDesign.backend.po.Qualitydata;
import com.GraduationDesign.backend.utils.RequestUtil;
import com.GraduationDesign.backend.utils.SnowFlakeUtil;
import com.GraduationDesign.backend.vo.CodeQuality;
import com.GraduationDesign.backend.vo.CodeQualityForPR;
import com.GraduationDesign.backend.vo.CodeQualityVO;
import com.GraduationDesign.backend.vo.PRInfo;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * @author DestinyCc
 * @date 2022/5/15
 */
@Service
public class CodeQualityServiceImpl implements CodeQualityService {
    public static final String CODE_QUALITY = "http://172.31.105.39:8000/api/code/quality/getPRCodeQuality";

    @Autowired
    RestTemplate restTemplate;

    @Autowired
    QualityMapper qualityMapper;

    @Autowired
    QualitydataMapper qualitydataMapper;

    @Override
    public void calculateCodeQuality(PRInfo prInfo, Integer reviewId){
        HttpEntity<PRInfo> httpEntity=new HttpEntity<>(prInfo);
        String response = RequestUtil.post(CODE_QUALITY, httpEntity).getBody();
        JSONObject obj = JSON.parseObject(response);
        List<CodeQualityForPR> res = JSON.parseArray(obj.getString("data"), CodeQualityForPR.class);
        for (CodeQualityForPR codeQualityForPR: res){
            Long currId = SnowFlakeUtil.nextId();
            insertQualityData(currId, codeQualityForPR.getCurr());
            Long deviationId = SnowFlakeUtil.nextId();
            insertQualityData(deviationId, codeQualityForPR.getDeviation());
            String fullFilename = codeQualityForPR.getFilename();
            Quality quality = Quality.builder()
                    .reviewId(reviewId)
                    .filename(fullFilename)
                    .currId(currId)
                    .deviationId(deviationId)
                    .build();
            qualityMapper.insert(quality);
        }
    }

    private void insertQualityData(Long id, CodeQualityForPR.Quality quality){
        Qualitydata qualitydata = new Qualitydata();
        BeanUtils.copyProperties(quality, qualitydata);
        qualitydata.round();
        qualitydata.setId(id);
        qualitydataMapper.insertSelective(qualitydata);
    }

    @Override
    public List<CodeQualityVO> getCodeQuality(Integer reviewId, String filename) {
        List<CodeQualityVO> codeQualityVO = new ArrayList<>();
        Quality quality = qualityMapper.selectByReviewIdAndFilename(reviewId, filename);
        if (Objects.isNull(quality)){
            CodeQualityVO complexity = new CodeQualityVO("复杂性", 0d, 0d);
            CodeQualityVO inheritance = new CodeQualityVO("可继承性", 0d, 0d);
            CodeQualityVO maintainability = new CodeQualityVO("可维护性", 0d, 0d);
            CodeQualityVO readability = new CodeQualityVO("可读性", 0d, 0d);
            CodeQualityVO reuseablity = new CodeQualityVO("可复用性", 0d, 0d);
            CodeQualityVO testability = new CodeQualityVO("可测试性", 0d, 0d);
            CodeQualityVO extendability = new CodeQualityVO("可扩展性", 0d, 0d);
            CodeQualityVO security = new CodeQualityVO("安全性", 0d, 0d);
            codeQualityVO.add(complexity);
            codeQualityVO.add(inheritance);
            codeQualityVO.add(maintainability);
            codeQualityVO.add(readability);
            codeQualityVO.add(reuseablity);
            codeQualityVO.add(testability);
            codeQualityVO.add(extendability);
            codeQualityVO.add(security);
            return codeQualityVO;
        }
        Long currId = quality.getCurrId();
        Qualitydata currData = qualitydataMapper.selectByPrimaryKey(currId);
        Long deviationId = quality.getDeviationId();
        Qualitydata devData = qualitydataMapper.selectByPrimaryKey(deviationId);
        CodeQualityVO complexity = new CodeQualityVO("复杂性", currData.getComplexity(), devData.getComplexity());
        CodeQualityVO inheritance = new CodeQualityVO("可继承性", currData.getInheritance(), devData.getInheritance());
        CodeQualityVO maintainability = new CodeQualityVO("可维护性", currData.getMaintainability(), devData.getMaintainability());
        CodeQualityVO readability = new CodeQualityVO("可读性", currData.getReadability(), devData.getReadability());
        CodeQualityVO reuseablity = new CodeQualityVO("可复用性", currData.getReuseablity(), devData.getReuseablity());
        CodeQualityVO testability = new CodeQualityVO("可测试性", currData.getTestability(), devData.getTestability());
        CodeQualityVO extendability = new CodeQualityVO("可扩展性", currData.getExtendability(), devData.getExtendability());
        CodeQualityVO security = new CodeQualityVO("安全性", currData.getSecurity(), devData.getSecurity());
        codeQualityVO.add(complexity);
        codeQualityVO.add(inheritance);
        codeQualityVO.add(maintainability);
        codeQualityVO.add(readability);
        codeQualityVO.add(reuseablity);
        codeQualityVO.add(testability);
        codeQualityVO.add(extendability);
        codeQualityVO.add(security);
        return codeQualityVO;
    }
}
